home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / x / volume3 / x11.3 / patch8 next >
Encoding:
Internet Message Format  |  1989-02-03  |  36.1 KB

  1. Path: uunet!wyse!mikew
  2. From: mikew@wyse.wyse.com (Mike Wexler)
  3. Newsgroups: comp.sources.x
  4. Subject: v03i009:  X11 Release 3, Patch8
  5. Message-ID: <2032@wyse.wyse.com>
  6. Date: 3 Feb 89 16:34:46 GMT
  7. Organization: Wyse Technology, San Jose
  8. Lines: 1245
  9. Approved: mikew@wyse.com
  10.  
  11. Submitted-by: mikew@wyse.com
  12. Posting-number: Volume 3, Issue 9
  13. Archive-name: x11.3/patch8
  14.  
  15.  
  16.  
  17.     Destroy procs were not being called for descendents of popups
  18.     when the parent of the popup was destroyed.
  19.  
  20.     Routines registered with XtAddInput can get called twice for every event.
  21.  
  22.     XtAppProcessEvent may process an XEvent even if told not to in the mask.
  23.  
  24.     XtAppProcessEvent might loop consuming as much cpu as it can get if
  25.     events are available from any source it was supposed to ignore.
  26.  
  27.     The display_accelerator method was being passed translations,
  28.     not accelerators.
  29.  
  30.     Installing accelerators into a destination with no translations
  31.     caused segmentation fault.
  32.  
  33. Server bugs:
  34.  
  35.     At apparently random times, when a window was destroyed, the Sun server
  36.     dumped core.
  37.  
  38.     Sun server allowed the default colormap to be destroyed, causing havoc.
  39.  
  40. *** old/lib/Xt/Create.c
  41. --- lib/Xt/Create.c
  42. ***************
  43. *** 1,5 ****
  44.   #ifndef lint
  45. ! static char Xrcsid[] = "$XConsortium: Create.c,v 1.47 88/10/17 20:19:21 swick Exp $";
  46.   /* $oHeader: Create.c,v 1.5 88/09/01 11:26:22 asente Exp $ */
  47.   #endif lint
  48.   
  49. --- 1,5 ----
  50.   #ifndef lint
  51. ! static char Xrcsid[] = "$XConsortium: Create.c,v 1.48 88/12/02 12:49:46 swick Exp $";
  52.   /* $oHeader: Create.c,v 1.5 88/09/01 11:26:22 asente Exp $ */
  53.   #endif lint
  54.   
  55. ***************
  56. *** 281,286 ****
  57. --- 281,293 ----
  58.       Window win;
  59.           if ((win = XtWindow(widget)) != NULL)
  60.           XDestroyWindow( XtDisplay(widget), win );
  61. +     return;
  62. +     /* don't update parent's popup_list, as we won't then be able to find
  63. +      * this child for Phase2Destroy.  This also allows for the possibility
  64. +      * that a destroy callback higher up in the hierarchy may care to
  65. +      * know that this popup child once existed.
  66. +      */
  67.       }
  68.       parent->core.num_popups--;
  69.       for (/*i=i*/; i<parent->core.num_popups; i++)
  70.  
  71.  
  72. *** lib/Xt/NextEvent.c.old
  73. --- lib/Xt/NextEvent.c
  74. ***************
  75. *** 1,5 ****
  76.   #ifndef lint
  77. ! static char Xrcsid[] = "$XConsortium: NextEvent.c,v 1.56 88/10/21 13:23:02 swick Exp $";
  78.   /* $oHeader: NextEvent.c,v 1.4 88/09/01 11:43:27 asente Exp $ */
  79.   #endif lint
  80.   
  81. --- 1,5 ----
  82.   #ifndef lint
  83. ! static char Xrcsid[] = "$XConsortium: NextEvent.c,v 1.59 89/01/18 17:04:01 swick Exp $";
  84.   /* $oHeader: NextEvent.c,v 1.4 88/09/01 11:43:27 asente Exp $ */
  85.   #endif lint
  86.   
  87. ***************
  88. *** 77,89 ****
  89.    *
  90.    * This routine returns when there is something to be done
  91.    *
  92.    *
  93. !  * _XtWaitForSomething( ignoreTimers, ignoreInputs, block, howlong, displaySet)
  94.    * Boolean ignoreTimers;     (Don't return if a timer would fire
  95.    *                Also implies forget timers exist)
  96.    *
  97.    * Boolean ignoreInputs;     (Ditto for input callbacks )
  98.    *
  99.    * Boolean block;         (Okay to block)
  100.    * TimeVal howlong;         (howlong to wait for if blocking and not
  101.    *                doing Timers... Null mean forever.
  102. --- 77,96 ----
  103.    *
  104.    * This routine returns when there is something to be done
  105.    *
  106. +  * Before calling this with ignoreInputs==False, app->outstandingQueue should
  107. +  * be checked; this routine will not verify that an alternate input source
  108. +  * has not already been enqueued.
  109.    *
  110. !  *
  111. !  * _XtWaitForSomething( ignoreTimers, ignoreInputs, ignoreEvents,
  112. !  *            block, howlong, appContext)
  113.    * Boolean ignoreTimers;     (Don't return if a timer would fire
  114.    *                Also implies forget timers exist)
  115.    *
  116.    * Boolean ignoreInputs;     (Ditto for input callbacks )
  117.    *
  118. +  * Boolean ignoreEvents;     (Ditto for X events)
  119. +  *
  120.    * Boolean block;         (Okay to block)
  121.    * TimeVal howlong;         (howlong to wait for if blocking and not
  122.    *                doing Timers... Null mean forever.
  123. ***************
  124. *** 90,99 ****
  125.    *                Maybe should mean shortest of both)
  126.    * XtAppContext app;         (Displays to check wait on)
  127.    * Returns display for which input is available, if any
  128.    */
  129. ! int _XtwaitForSomething(ignoreTimers, ignoreInputs, block, howlong, app)
  130.       Boolean ignoreTimers;
  131.       Boolean ignoreInputs;
  132.       Boolean block;
  133.       unsigned long *howlong;
  134.       XtAppContext app;
  135. --- 97,114 ----
  136.    *                Maybe should mean shortest of both)
  137.    * XtAppContext app;         (Displays to check wait on)
  138.    * Returns display for which input is available, if any
  139. +  * and if ignoreEvents==False, else returns -1
  140. +  *
  141. +  * if ignoring everything && block=True && howlong=NULL, you'll have
  142. +  * lots of time for coffee; better not try it!  In fact, it probably
  143. +  * makes little sense to do this regardless of the value of howlong
  144. +  * (bottom line is, we don't bother checking here).
  145.    */
  146. ! int _XtwaitForSomething(ignoreTimers, ignoreInputs, ignoreEvents,
  147. !             block, howlong, app)
  148.       Boolean ignoreTimers;
  149.       Boolean ignoreInputs;
  150. +     Boolean ignoreEvents;
  151.       Boolean block;
  152.       unsigned long *howlong;
  153.       XtAppContext app;
  154. ***************
  155. *** 147,154 ****
  156.               wmaskfd = zero;
  157.               emaskfd = zero;
  158.           }
  159. !         for (d = 0; d < app->count; d++) {
  160. !             FD_SET (ConnectionNumber(app->list[d]), &rmaskfd);
  161.           }
  162.           nfound = select (app->fds.nfds, (int *) &rmaskfd,
  163.               (int *) &wmaskfd, (int *) &emaskfd, wait_time_ptr);
  164. --- 162,171 ----
  165.               wmaskfd = zero;
  166.               emaskfd = zero;
  167.           }
  168. !         if (!ignoreEvents) {
  169. !             for (d = 0; d < app->count; d++) {
  170. !             FD_SET (ConnectionNumber(app->list[d]), &rmaskfd);
  171. !             }
  172.           }
  173.           nfound = select (app->fds.nfds, (int *) &rmaskfd,
  174.               (int *) &wmaskfd, (int *) &emaskfd, wait_time_ptr);
  175. ***************
  176. *** 198,203 ****
  177. --- 215,221 ----
  178.               }
  179.       }
  180.       if(ignoreInputs) {
  181. +         if (ignoreEvents) return -1; /* then only doing timers */
  182.           for (d = 0; d < app->count; d++) {
  183.           if (FD_ISSET(ConnectionNumber(app->list[d]), &rmaskfd)) {
  184.               return d;
  185. ***************
  186. *** 207,222 ****
  187.       ret = -1;
  188.       for (i = 0; i < app->fds.nfds && nfound > 0; i++) {
  189.           if (FD_ISSET (i, &rmaskfd)) {
  190. !         for (d = 0; d < app->count; d++) {
  191. !             if (i == ConnectionNumber(app->list[d])) {
  192. !             if (ret == -1) ret = d;
  193. !             goto ENDILOOP;
  194.               }
  195.           }
  196.   
  197.           app->selectRqueue[i]->ie_oq = app->outstandingQueue;
  198.           app->outstandingQueue = app->selectRqueue[i];
  199. -         nfound--;
  200.           }
  201.           if (FD_ISSET (i, &wmaskfd)) {
  202.           app->selectWqueue[i]->ie_oq = app->outstandingQueue;
  203. --- 225,242 ----
  204.       ret = -1;
  205.       for (i = 0; i < app->fds.nfds && nfound > 0; i++) {
  206.           if (FD_ISSET (i, &rmaskfd)) {
  207. !         nfound--;
  208. !         if (!ignoreEvents) {
  209. !             for (d = 0; d < app->count; d++) {
  210. !             if (i == ConnectionNumber(app->list[d])) {
  211. !                 if (ret == -1) ret = d;
  212. !                 goto ENDILOOP;
  213. !             }
  214.               }
  215.           }
  216.   
  217.           app->selectRqueue[i]->ie_oq = app->outstandingQueue;
  218.           app->outstandingQueue = app->selectRqueue[i];
  219.           }
  220.           if (FD_ISSET (i, &wmaskfd)) {
  221.           app->selectWqueue[i]->ie_oq = app->outstandingQueue;
  222. ***************
  223. *** 362,368 ****
  224.       InputEvent *sptr;
  225.       XtInputMask condition = (XtInputMask) Condition;
  226.       
  227. !     sptr = (InputEvent *)XtMalloc((unsigned) sizeof (*sptr));
  228.       if(condition == XtInputReadMask){
  229.           sptr->ie_next = app->selectRqueue[source];
  230.           app->selectRqueue[source] = sptr;
  231. --- 382,388 ----
  232.       InputEvent *sptr;
  233.       XtInputMask condition = (XtInputMask) Condition;
  234.       
  235. !     sptr = XtNew(InputEvent);
  236.       if(condition == XtInputReadMask){
  237.           sptr->ie_next = app->selectRqueue[source];
  238.           app->selectRqueue[source] = sptr;
  239. ***************
  240. *** 474,491 ****
  241.       struct timeval  cur_time;
  242.       struct timezone cur_timezone;
  243.   
  244.       if (app->fds.count > 0) {
  245.           /* Call _XtwaitForSomething to get input queued up */
  246. !         (void) _XtwaitForSomething(TRUE, FALSE, FALSE,
  247.           (unsigned long *)NULL, app);
  248.       }
  249. -     for (ie_ptr = app->outstandingQueue; ie_ptr != NULL;) {
  250. -         app->outstandingQueue = ie_ptr->ie_oq;
  251. -         ie_ptr ->ie_oq = NULL;
  252. -         IeCallProc(ie_ptr);
  253. -         ie_ptr = app->outstandingQueue;
  254. -     }
  255.       if (app->timerQueue != NULL) {    /* check timeout queue */
  256.           (void) gettimeofday (&cur_time, &cur_timezone);
  257.           while(IS_AFTER (app->timerQueue->te_timer_value, cur_time)) {
  258. --- 494,514 ----
  259.       struct timeval  cur_time;
  260.       struct timezone cur_timezone;
  261.   
  262. + #define DrainQueue() \
  263. +     for (ie_ptr = app->outstandingQueue; ie_ptr != NULL;) { \
  264. +         app->outstandingQueue = ie_ptr->ie_oq;        \
  265. +         ie_ptr ->ie_oq = NULL;                \
  266. +         IeCallProc(ie_ptr);                    \
  267. +         ie_ptr = app->outstandingQueue;            \
  268. +     }
  269. + /*enddef*/
  270. +     DrainQueue();
  271.       if (app->fds.count > 0) {
  272.           /* Call _XtwaitForSomething to get input queued up */
  273. !         (void) _XtwaitForSomething(TRUE, FALSE, TRUE, FALSE,
  274.           (unsigned long *)NULL, app);
  275. +         DrainQueue();
  276.       }
  277.       if (app->timerQueue != NULL) {    /* check timeout queue */
  278.           (void) gettimeofday (&cur_time, &cur_timezone);
  279.           while(IS_AFTER (app->timerQueue->te_timer_value, cur_time)) {
  280. ***************
  281. *** 498,503 ****
  282. --- 521,527 ----
  283.                 if (app->timerQueue == NULL) break;
  284.           }
  285.       }
  286. + #undef DrainQueue
  287.   }
  288.   
  289.   /* If there are any work procs, call them.  Return whether we did so */
  290. ***************
  291. *** 573,579 ****
  292.       /* We're ready to wait...if there is a work proc, call it */
  293.       if (CallWorkProc(app)) continue;
  294.   
  295. !     d = _XtwaitForSomething(FALSE, FALSE, TRUE,
  296.                   (unsigned long *) NULL, app);
  297.   
  298.       if (d != -1) {
  299. --- 597,603 ----
  300.       /* We're ready to wait...if there is a work proc, call it */
  301.       if (CallWorkProc(app)) continue;
  302.   
  303. !     d = _XtwaitForSomething(FALSE, FALSE, FALSE, TRUE,
  304.                   (unsigned long *) NULL, app);
  305.   
  306.       if (d != -1) {
  307. ***************
  308. *** 622,630 ****
  309.           }
  310.       
  311.           if (mask & XtIMAlternateInput) {
  312. !         if (app->fds.count > 0) {
  313.               /* Call _XtwaitForSomething to get input queued up */
  314. !             (void) _XtwaitForSomething(TRUE, FALSE, FALSE,
  315.                   (unsigned long *)NULL, app);
  316.           }
  317.           if (app->outstandingQueue != NULL) {
  318. --- 646,654 ----
  319.           }
  320.       
  321.           if (mask & XtIMAlternateInput) {
  322. !         if (app->fds.count > 0 && app->outstandingQueue == NULL) {
  323.               /* Call _XtwaitForSomething to get input queued up */
  324. !             (void) _XtwaitForSomething(TRUE, FALSE, TRUE, FALSE,
  325.                   (unsigned long *)NULL, app);
  326.           }
  327.           if (app->outstandingQueue != NULL) {
  328. ***************
  329. *** 654,663 ****
  330.   
  331.           if (CallWorkProc(app)) continue;
  332.   
  333. !         d = _XtwaitForSomething(FALSE, FALSE, TRUE,
  334.                       (unsigned long *) NULL, app);
  335.           
  336. !         if (d != -1) {
  337.           XNextEvent(app->list[d], &event);
  338.           app->last = d;
  339.           if (event.xany.type == MappingNotify) {
  340. --- 678,691 ----
  341.   
  342.           if (CallWorkProc(app)) continue;
  343.   
  344. !         d = _XtwaitForSomething(
  345. !                     (mask & XtIMTimer ? FALSE : TRUE),
  346. !                     (mask & XtIMAlternateInput ? FALSE : TRUE),
  347. !                     (mask & XtIMXEvent ? FALSE : TRUE),
  348. !                     TRUE,
  349.                       (unsigned long *) NULL, app);
  350.           
  351. !         if (mask & XtIMXEvent && d != -1) {
  352.           XNextEvent(app->list[d], &event);
  353.           app->last = d;
  354.           if (event.xany.type == MappingNotify) {
  355. ***************
  356. *** 708,714 ****
  357.       else {
  358.           /* This won't cause a wait, but will enqueue any input */
  359.   
  360. !         if(_XtwaitForSomething(TRUE, FALSE, FALSE, (unsigned long *) NULL,
  361.               app) != -1) ret |= XtIMXEvent;
  362.           if (app->outstandingQueue != NULL) ret |= XtIMAlternateInput;
  363.       }
  364. --- 736,742 ----
  365.       else {
  366.           /* This won't cause a wait, but will enqueue any input */
  367.   
  368. !         if(_XtwaitForSomething(TRUE, FALSE, FALSE, FALSE, (unsigned long *) NULL,
  369.               app) != -1) ret |= XtIMXEvent;
  370.           if (app->outstandingQueue != NULL) ret |= XtIMAlternateInput;
  371.       }
  372. ***************
  373. *** 723,735 ****
  374.       struct timeval  cur_time;
  375.       struct timezone cur_timezone;
  376.   
  377.       if (app->fds.count > 0) {
  378.           /* Call _XtwaitForSomething to get input queued up */
  379. !         (void) _XtwaitForSomething(TRUE, FALSE, FALSE,
  380.               (unsigned long *)NULL, app);
  381.       }
  382.   
  383. -     if (app->outstandingQueue != NULL) return TRUE;
  384.       if (app->timerQueue != NULL) {    /* check timeout queue */
  385.           (void) gettimeofday (&cur_time, &cur_timezone);
  386.           if (IS_AFTER (app->timerQueue->te_timer_value, cur_time)) return TRUE;
  387. --- 751,765 ----
  388.       struct timeval  cur_time;
  389.       struct timezone cur_timezone;
  390.   
  391. +     if (app->outstandingQueue != NULL) return TRUE;
  392.       if (app->fds.count > 0) {
  393.           /* Call _XtwaitForSomething to get input queued up */
  394. !         (void) _XtwaitForSomething(TRUE, FALSE, TRUE, FALSE,
  395.               (unsigned long *)NULL, app);
  396. +         if (app->outstandingQueue != NULL) return TRUE;
  397.       }
  398.   
  399.       if (app->timerQueue != NULL) {    /* check timeout queue */
  400.           (void) gettimeofday (&cur_time, &cur_timezone);
  401.           if (IS_AFTER (app->timerQueue->te_timer_value, cur_time)) return TRUE;
  402. ***************
  403. *** 769,775 ****
  404.           return FALSE;
  405.           }
  406.   
  407. !         d = _XtwaitForSomething(FALSE, FALSE, TRUE,
  408.               (unsigned long *) NULL, app);
  409.   
  410.           if (d != -1) {
  411. --- 799,805 ----
  412.           return FALSE;
  413.           }
  414.   
  415. !         d = _XtwaitForSomething(FALSE, FALSE, FALSE, TRUE,
  416.               (unsigned long *) NULL, app);
  417.   
  418.           if (d != -1) {
  419.  
  420.  
  421. *** lib/Xt/InitialI.h.old
  422. --- lib/Xt/InitialI.h
  423. ***************
  424. *** 1,4 ****
  425. ! /* $XConsortium: InitialI.h,v 1.8 88/10/19 08:35:49 swick Exp $ */
  426.   /* $oHeader: InitializeI.h,v 1.8 88/09/01 11:25:04 asente Exp $ */
  427.   /***********************************************************
  428.   Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  429. --- 1,4 ----
  430. ! /* $XConsortium: InitialI.h,v 1.9 89/01/18 17:05:57 swick Exp $ */
  431.   /* $oHeader: InitializeI.h,v 1.8 88/09/01 11:25:04 asente Exp $ */
  432.   /***********************************************************
  433.   Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  434. ***************
  435. *** 107,116 ****
  436.   extern int _XtAppDestroyCount;
  437.   extern int _XtDpyDestroyCount;
  438.   
  439. ! extern int _XtwaitForSomething(); /* ignoreTimers, ignoreInputs, block, 
  440. !                     howlong, dset */
  441.       /* Boolean ignoreTimers; */
  442.       /* Boolean ignoreInputs; */
  443.       /* Boolean block; */
  444.       /* unsigned long *howlong; */
  445.       /* XtAppContext app */
  446. --- 107,117 ----
  447.   extern int _XtAppDestroyCount;
  448.   extern int _XtDpyDestroyCount;
  449.   
  450. ! extern int _XtwaitForSomething(); /* ignoreTimers, ignoreInputs, ignoreEvents,
  451. !                      block, howlong, appContext */
  452.       /* Boolean ignoreTimers; */
  453.       /* Boolean ignoreInputs; */
  454. +     /* Boolean ignoreEvents; */
  455.       /* Boolean block; */
  456.       /* unsigned long *howlong; */
  457.       /* XtAppContext app */
  458.  
  459.  
  460. *** lib/Xt/Shell.c.old
  461. --- lib/Xt/Shell.c
  462. ***************
  463. *** 1,5 ****
  464.   #ifndef lint
  465. ! static char Xrcsid[] = "$XConsortium: Shell.c,v 1.45 88/10/19 09:21:48 swick Exp $";
  466.   /* $oHeader: Shell.c,v 1.7 88/09/01 11:57:00 asente Exp $ */
  467.   #endif lint
  468.   
  469. --- 1,5 ----
  470.   #ifndef lint
  471. ! static char Xrcsid[] = "$XConsortium: Shell.c,v 1.46 89/01/18 17:04:58 swick Exp $";
  472.   /* $oHeader: Shell.c,v 1.7 88/09/01 11:57:00 asente Exp $ */
  473.   #endif lint
  474.   
  475. ***************
  476. *** 1265,1271 ****
  477.           }
  478.           return TRUE;
  479.           } else {
  480. !         if (_XtwaitForSomething(TRUE, TRUE, TRUE, &timeout,
  481.               app) != -1) continue;
  482.           if (timeout == 0)
  483.             return FALSE;
  484. --- 1265,1271 ----
  485.           }
  486.           return TRUE;
  487.           } else {
  488. !         if (_XtwaitForSomething(TRUE, TRUE, FALSE, TRUE, &timeout,
  489.               app) != -1) continue;
  490.           if (timeout == 0)
  491.             return FALSE;
  492.  
  493.  
  494. *** /tmp/,RCSt1a05545    Fri Jan 20 08:06:10 1989
  495. --- lib/Xt/TMstate.c    Fri Jan 20 08:05:58 1989
  496. ***************
  497. *** 1,5 ****
  498.   #ifndef lint
  499. ! static char Xrcsid[] = "$XConsortium: TMstate.c,v 1.61 88/09/26 09:30:45 swick Exp $";
  500.   /* $oHeader: TMstate.c,v 1.5 88/09/01 17:17:29 asente Exp $ */
  501.   #endif lint
  502.   /*LINTLIBRARY*/
  503. --- 1,5 ----
  504.   #ifndef lint
  505. ! static char Xrcsid[] = "$XConsortium: TMstate.c,v 1.65 89/01/20 08:05:17 swick Exp $";
  506.   /* $oHeader: TMstate.c,v 1.5 88/09/01 17:17:29 asente Exp $ */
  507.   #endif lint
  508.   /*LINTLIBRARY*/
  509. ***************
  510. *** 41,46 ****
  511. --- 41,63 ----
  512.   
  513.   #define StringToAction(string)    ((XtAction) StringToQuark(string))
  514.   
  515. + #define STR_THRESHOLD 25
  516. + #define STR_INCAMOUNT 100
  517. + #define CHECK_STR_OVERFLOW \
  518. +     if (str - *buf > *len - STR_THRESHOLD) {        \
  519. +     String old = *buf;                \
  520. +     *buf = XtRealloc(old, *len += STR_INCAMOUNT);    \
  521. +     str = str - old + *buf;                \
  522. +     }
  523. + #define ExpandToFit(more) \
  524. +     if (str - *buf > *len - STR_THRESHOLD - strlen(more)) {         \
  525. +     String old = *buf;                        \
  526. +     *buf = XtRealloc(old, *len += STR_INCAMOUNT + strlen(more));    \
  527. +     str = str - old + *buf;                        \
  528. +     }
  529.   static void FreeActions(action)
  530.     register ActionPtr action;
  531.   {
  532. ***************
  533. *** 60,93 ****
  534.       }
  535.   }
  536.   
  537. ! static String PrintModifiers(str, mask, mod)
  538.       String str;
  539.       unsigned long mask, mod;
  540.   {
  541. !     if (mask & ShiftMask)
  542. !     (void) sprintf(str, "%sShift", ((mod & ShiftMask) ? "" : "~"));
  543. !     if (mask & ControlMask)
  544. !     (void) sprintf(str, "%sCtrl", ((mod & ControlMask) ? "" : "~"));
  545. !     if (mask & LockMask)
  546. !     (void) sprintf(str, "%sLock", ((mod & LockMask) ? "" : "~"));
  547. !     if (mask & Mod1Mask)
  548. !     (void) sprintf(str, "%sMeta", ((mod & Mod1Mask) ? "" : "~"));
  549. !     if (mask & Mod2Mask)
  550. !     (void) sprintf(str, "%sMod2", ((mod & Mod2Mask) ? "" : "~"));
  551. !     if (mask & Mod3Mask)
  552. !     (void) sprintf(str, "%sMod3", ((mod & Mod3Mask) ? "" : "~"));
  553. !     if (mask & Mod4Mask)
  554. !     (void) sprintf(str, "%sMod4", ((mod & Mod4Mask) ? "" : "~"));
  555. !     if (mask & Mod5Mask)
  556. !     (void) sprintf(str, "%sMod5", ((mod & Mod5Mask) ? "" : "~"));
  557. !     str += strlen(str);
  558.       return str;
  559.   }
  560.   
  561. ! static String PrintEventType(str, event)
  562.       register String str;
  563.       unsigned long event;
  564.   {
  565.       switch (event) {
  566.   #define PRINTEVENT(event) case event: (void) sprintf(str, "<event>"); break;
  567.       PRINTEVENT(KeyPress)
  568. --- 77,139 ----
  569.       }
  570.   }
  571.   
  572. ! static String PrintModifiers(buf, len, str, mask, mod)
  573. !     String *buf;
  574. !     int *len;
  575.       String str;
  576.       unsigned long mask, mod;
  577.   {
  578. !     Boolean notfirst = False;
  579. !     CHECK_STR_OVERFLOW;
  580. ! #if defined(__STDC__) && !defined(UNIXCPP)
  581. ! #define MASKNAME(modname) modname##Mask
  582. ! #else
  583. ! #define MASKNAME(modname) modname/**/Mask
  584. ! #endif
  585. ! #define PRINTMOD(modname) \
  586. !     if (mask & MASKNAME(modname)) {     \
  587. !     if (! (mod & MASKNAME(modname))) \
  588. !         *str++ = '~';         \
  589. !     else if (notfirst)         \
  590. !         *str++ = ' ';         \
  591. !     *str = '\0';             \
  592. !     strcat(str, "modname");         \
  593. !     str += strlen(str);         \
  594. !     notfirst = True;         \
  595. !     }
  596. ! #define CtrlMask ControlMask
  597. !     PRINTMOD(Shift);
  598. !     PRINTMOD(Ctrl);
  599. !     PRINTMOD(Lock);
  600. !     PRINTMOD(Mod1);
  601. !     PRINTMOD(Mod2);
  602. !     PRINTMOD(Mod3);
  603. !     PRINTMOD(Mod4);
  604. !     PRINTMOD(Mod5);
  605. !     PRINTMOD(Button1);
  606. !     PRINTMOD(Button2);
  607. !     PRINTMOD(Button3);
  608. !     PRINTMOD(Button4);
  609. !     PRINTMOD(Button5);
  610. ! #undef MASKNAME
  611. ! #undef PRINTMOD
  612. ! #undef CtrlMask
  613.       return str;
  614.   }
  615.   
  616. ! static String PrintEventType(buf, len, str, event)
  617. !     String *buf;
  618. !     int *len;
  619.       register String str;
  620.       unsigned long event;
  621.   {
  622. +     CHECK_STR_OVERFLOW;
  623.       switch (event) {
  624.   #define PRINTEVENT(event) case event: (void) sprintf(str, "<event>"); break;
  625.       PRINTEVENT(KeyPress)
  626. ***************
  627. *** 131,140 ****
  628.       return str;
  629.   }
  630.   
  631. ! static String PrintCode(str, mask, code)
  632.       register String str;
  633.       unsigned long mask, code;
  634.   {
  635.       if (mask != 0) {
  636.       if (mask != (unsigned long)~0L)
  637.           (void) sprintf(str, "0x%lx:0x%lx", mask, code);
  638. --- 177,189 ----
  639.       return str;
  640.   }
  641.   
  642. ! static String PrintCode(buf, len, str, mask, code)
  643. !     String *buf;
  644. !     int *len;
  645.       register String str;
  646.       unsigned long mask, code;
  647.   {
  648. +     CHECK_STR_OVERFLOW;
  649.       if (mask != 0) {
  650.       if (mask != (unsigned long)~0L)
  651.           (void) sprintf(str, "0x%lx:0x%lx", mask, code);
  652. ***************
  653. *** 144,165 ****
  654.       return str;
  655.   }
  656.   
  657. ! static String PrintEvent(str, event)
  658.       register String str;
  659.       register Event *event;
  660.   {
  661. !     str = PrintModifiers(str, event->modifierMask, event->modifiers);
  662. !     str = PrintEventType(str, event->eventType);
  663. !     str = PrintCode(str, event->eventCodeMask, event->eventCode);
  664.       return str;
  665.   }
  666.   
  667. ! static String PrintParams(str, params, num_params)
  668.       register String str, *params;
  669.       Cardinal num_params;
  670.   {
  671.       register Cardinal i;
  672.       for (i = 0; i<num_params; i++) {
  673.       if (i != 0) (void) sprintf(str, ", ");
  674.       str += strlen(str);
  675.       (void) sprintf(str, "\"%s\"", params[i]);
  676. --- 193,243 ----
  677.       return str;
  678.   }
  679.   
  680. ! static String PrintLateModifiers(buf, len, str, lateModifiers)
  681. !     String *buf;
  682. !     int *len;
  683.       register String str;
  684. +     LateBindingsPtr lateModifiers;
  685. + {
  686. +     for (; lateModifiers->keysym != NULL; lateModifiers++) {
  687. +     CHECK_STR_OVERFLOW;
  688. +     if (lateModifiers->knot) {
  689. +         *str++ = '~';
  690. +         *str = '\0';
  691. +     }
  692. +     strcat(str, XKeysymToString(lateModifiers->keysym));
  693. +     str += strlen(str);
  694. +     if (lateModifiers->pair) {
  695. +         *(str -= 2) = '\0';    /* strip "_L" */
  696. +         lateModifiers++;    /* skip _R keysym */
  697. +     }
  698. +     }
  699. +     return str;
  700. + }
  701. + static String PrintEvent(buf, len, str, event)
  702. +     String *buf;
  703. +     int *len;
  704. +     register String str;
  705.       register Event *event;
  706.   {
  707. !     str = PrintModifiers(buf, len, str, event->modifierMask, event->modifiers);
  708. !     if (event->lateModifiers != NULL)
  709. !     str = PrintLateModifiers(buf, len, str, event->lateModifiers);
  710. !     str = PrintEventType(buf, len, str, event->eventType);
  711. !     str = PrintCode(buf, len, str, event->eventCodeMask, event->eventCode);
  712.       return str;
  713.   }
  714.   
  715. ! static String PrintParams(buf, len, str, params, num_params)
  716. !     String *buf;
  717. !     int *len;
  718.       register String str, *params;
  719.       Cardinal num_params;
  720.   {
  721.       register Cardinal i;
  722.       for (i = 0; i<num_params; i++) {
  723. +     ExpandToFit( params[i] );
  724.       if (i != 0) (void) sprintf(str, ", ");
  725.       str += strlen(str);
  726.       (void) sprintf(str, "\"%s\"", params[i]);
  727. ***************
  728. *** 168,183 ****
  729.       return str;
  730.   }
  731.   
  732. ! static String PrintActions(str, actions, quarkTable)
  733.       register String str;
  734.       register ActionPtr actions;
  735.       XrmQuark* quarkTable;
  736.   {
  737. !     while (actions != NULL && actions->token != NULL) {
  738. !         (void) sprintf(
  739. !             str, " %s(", XrmQuarkToString(quarkTable[actions->index]));
  740.       str += strlen(str);
  741. !     str = PrintParams(str, actions->params, (Cardinal)actions->num_params);
  742.       str += strlen(str);
  743.       (void) sprintf(str, ")");
  744.       str += strlen(str);
  745. --- 246,264 ----
  746.       return str;
  747.   }
  748.   
  749. ! static String PrintActions(buf, len, str, actions, quarkTable)
  750. !     String *buf;
  751. !     int *len;
  752.       register String str;
  753.       register ActionPtr actions;
  754.       XrmQuark* quarkTable;
  755.   {
  756. !     while (actions != NULL /* && actions->token != NULL */) {
  757. !     String proc = XrmQuarkToString(quarkTable[actions->index]);
  758. !     ExpandToFit( proc );
  759. !         (void) sprintf(str, " %s(", proc);
  760.       str += strlen(str);
  761. !     str = PrintParams(buf, len, str, actions->params, (Cardinal)actions->num_params);
  762.       str += strlen(str);
  763.       (void) sprintf(str, ")");
  764.       str += strlen(str);
  765. ***************
  766. *** 1002,1007 ****
  767. --- 1083,1089 ----
  768.       if (unbound != 0) ReportUnboundActions(tm, stateTable);
  769.   }
  770.   
  771. + static
  772.   void _XtBindAccActions(widget,stateTable,index,accBindings)
  773.       Widget        widget;
  774.       XtTranslations  stateTable;
  775. ***************
  776. *** 1491,1527 ****
  777.   void XtInstallAccelerators(destination,source)
  778.       Widget destination,source;
  779.   {
  780. -     char str[100];
  781. -     XtTranslations temp;
  782.       XtBoundAccActions accBindings;
  783.       if ((!XtIsWindowObject(source)) ||
  784.           source->core.accelerators == NULL) return;
  785. !     if (source->core.accelerators != NULL 
  786. !         && source->core.accelerators->accProcTbl == NULL)
  787.           _XtBindAccActions(source,source->core.accelerators,0,&accBindings);
  788. !     _XtInitializeStateTable(&temp);
  789. !     temp->clickTime = source->core.accelerators->clickTime;
  790. !     if (source->core.accelerators->operation == XtTableOverride) {
  791. !         MergeTables(temp,source->core.accelerators,FALSE,accBindings);
  792. !         MergeTables(temp, destination->core.tm.translations,FALSE,
  793. !                destination->core.tm.translations->accProcTbl);
  794.       }
  795. !     else { 
  796. !         MergeTables(temp, destination->core.tm.translations,FALSE,
  797. !                destination->core.tm.translations->accProcTbl);
  798. !         MergeTables(temp,source->core.accelerators,FALSE,accBindings);
  799.       }
  800. -     destination->core.tm.translations = temp;
  801.       if (XtIsRealized(destination))
  802.           _XtInstallTranslations(destination,
  803.                destination->core.tm.translations);
  804.       XtAddCallback(source, XtNdestroyCallback,
  805. !         RemoveAccelerators,(caddr_t)temp);
  806.       if (XtClass(source)->core_class.display_accelerator != NULL){
  807.            str[0] = '\0';
  808. !          (void) PrintEvent(&str[0],
  809. !                 &source->core.tm.translations->eventObjTbl[0].event);
  810. !          (*(XtClass(source)->core_class.display_accelerator))(source,str);
  811.       }
  812.   }         
  813.   void XtInstallAllAccelerators(destination,source)
  814. --- 1573,1632 ----
  815.   void XtInstallAccelerators(destination,source)
  816.       Widget destination,source;
  817.   {
  818.       XtBoundAccActions accBindings;
  819.       if ((!XtIsWindowObject(source)) ||
  820.           source->core.accelerators == NULL) return;
  821. ! /*    if (source->core.accelerators->accProcTbl == NULL)
  822. !  *  %%%
  823. !  *  The spec is not clear on when actions specified in accelerators are bound;
  824. !  *  The most useful (and easiest) thing seems to be to bind them at this time
  825. !  *  (rather than at Realize).  Under the current code the preceeding test
  826. !  *  seems always to be True, thus guaranteeing accBindings is always set
  827. !  *  before being used below.
  828. !  */
  829.           _XtBindAccActions(source,source->core.accelerators,0,&accBindings);
  830. !     if (destination->core.tm.translations == NULL) {
  831. !     destination->core.tm.translations = source->core.accelerators;
  832. !     destination->core.tm.translations->accProcTbl = accBindings;
  833.       }
  834. !     else {
  835. !     XtTranslations temp;
  836. !     _XtInitializeStateTable(&temp);
  837. !     temp->clickTime = source->core.accelerators->clickTime;
  838. !     if (source->core.accelerators->operation == XtTableOverride) {
  839. !         MergeTables(temp,source->core.accelerators,FALSE,accBindings);
  840. !         MergeTables(temp, destination->core.tm.translations,FALSE,
  841. !            destination->core.tm.translations->accProcTbl);
  842. !     }
  843. !     else { 
  844. !         MergeTables(temp, destination->core.tm.translations,FALSE,
  845. !            destination->core.tm.translations->accProcTbl);
  846. !         MergeTables(temp,source->core.accelerators,FALSE,accBindings);
  847. !     }
  848. !     destination->core.tm.translations = temp;
  849.       }
  850.       if (XtIsRealized(destination))
  851.           _XtInstallTranslations(destination,
  852.                destination->core.tm.translations);
  853.       XtAddCallback(source, XtNdestroyCallback,
  854. !         RemoveAccelerators,(caddr_t)destination->core.tm.translations);
  855.       if (XtClass(source)->core_class.display_accelerator != NULL){
  856. +      char *buf = XtMalloc(100);
  857. +      int len = 100;
  858. +      String str = buf;
  859. +      int i;
  860.            str[0] = '\0';
  861. !      for (i = 0; i < source->core.accelerators->numEvents;) {
  862. !          str = PrintEvent(&str, &len, str,
  863. !                 &source->core.accelerators->eventObjTbl[i].event);
  864. !          if (++i == source->core.accelerators->numEvents) break;
  865. !          else {
  866. !          *str++ = '\n';
  867. !          *str = '\0';
  868. !          }
  869. !      }
  870. !          (*(XtClass(source)->core_class.display_accelerator))(source,buf);
  871. !      XtFree(buf);
  872.       }
  873.   }         
  874.   void XtInstallAllAccelerators(destination,source)
  875. ***************
  876. *** 1574,1581 ****
  877.   
  878.   }
  879.   
  880. ! static void PrintState(start, str, state, quarkTable, eot)
  881. !     register String start, str;
  882.       StatePtr state;
  883.       XrmQuark* quarkTable;
  884.       EventObjPtr eot;
  885. --- 1679,1688 ----
  886.   
  887.   }
  888.   
  889. ! static void PrintState(buf, len, str, state, quarkTable, eot)
  890. !     String *buf;
  891. !     int *len;
  892. !     register String str;
  893.       StatePtr state;
  894.       XrmQuark* quarkTable;
  895.       EventObjPtr eot;
  896. ***************
  897. *** 1584,1608 ****
  898.       /* print the current state */
  899.       if (state == NULL) return;
  900.   
  901. !     str = PrintEvent(str, &eot[state->index].event);
  902. !     str += strlen(str);
  903.       if (state->actions != NULL) {
  904. !     String temp = str;
  905.       (void) sprintf(str, "%s: ", (state->cycle ? "(+)" : ""));
  906.       while (*str) str++;
  907. !     (void) PrintActions(str, state->actions, quarkTable);
  908. !     (void) printf("%s\n", start);
  909. !     str = temp; *str = '\0';
  910.       }
  911.   
  912.       /* print succeeding states */
  913.       if (!state->cycle)
  914. !     PrintState(start, str, state->nextLevel, quarkTable, eot);
  915.   
  916.       str = old; *str = '\0';
  917.   
  918.       /* print sibling states */
  919. !     PrintState(start, str, state->next, quarkTable, eot);
  920.       *str = '\0';
  921.   
  922.   }
  923. --- 1691,1715 ----
  924.       /* print the current state */
  925.       if (state == NULL) return;
  926.   
  927. !     str = PrintEvent(buf, len, str, &eot[state->index].event);
  928.       if (state->actions != NULL) {
  929. !     int offset = str - *buf;
  930. !     CHECK_STR_OVERFLOW;
  931.       (void) sprintf(str, "%s: ", (state->cycle ? "(+)" : ""));
  932.       while (*str) str++;
  933. !     (void) PrintActions(buf, len, str, state->actions, quarkTable);
  934. !     (void) printf("%s\n", *buf);
  935. !     str = *buf + offset; *str = '\0';
  936.       }
  937.   
  938.       /* print succeeding states */
  939.       if (!state->cycle)
  940. !     PrintState(buf, len, str, state->nextLevel, quarkTable, eot);
  941.   
  942.       str = old; *str = '\0';
  943.   
  944.       /* print sibling states */
  945. !     PrintState(buf, len, str, state->next, quarkTable, eot);
  946.       *str = '\0';
  947.   
  948.   }
  949. ***************
  950. *** 1615,1631 ****
  951.       XtTranslations translations;
  952.   {
  953.       register Cardinal i;
  954. !     char buf[1000];
  955.   
  956.       for (i = 0; i < translations->numEvents; i++) {
  957.       buf[0] = '\0';
  958.       PrintState(
  959. !        &buf[0],
  960. !        &buf[0],
  961.          translations->eventObjTbl[i].state,
  962.              translations->quarkTable,
  963.          translations->eventObjTbl);
  964.       }
  965.   }
  966.   
  967.   /***********************************************************************
  968. --- 1722,1741 ----
  969.       XtTranslations translations;
  970.   {
  971.       register Cardinal i;
  972. !     int len = 1000;
  973. !     char *buf = XtMalloc(1000);
  974.   
  975.       for (i = 0; i < translations->numEvents; i++) {
  976.       buf[0] = '\0';
  977.       PrintState(
  978. !        &buf,
  979. !        &len,
  980. !        buf,
  981.          translations->eventObjTbl[i].state,
  982.              translations->quarkTable,
  983.          translations->eventObjTbl);
  984.       }
  985. +     XtFree(buf);
  986.   }
  987.   
  988.   /***********************************************************************
  989.  
  990.  
  991. *** /tmp/,RCSt1a09958    Thu Dec 22 17:26:10 1988
  992. --- server/dix/resource.c    Thu Dec 22 16:58:08 1988
  993. ***************
  994. *** 22,28 ****
  995.   
  996.   ********************************************************/
  997.   
  998. ! /* $XConsortium: resource.c,v 1.66 88/09/06 15:41:20 jim Exp $ */
  999.   
  1000.   /*    Routines to manage various kinds of resources:
  1001.    *
  1002. --- 22,28 ----
  1003.   
  1004.   ********************************************************/
  1005.   
  1006. ! /* $XConsortium: resource.c,v 1.67 88/12/22 16:58:58 rws Exp $ */
  1007.   
  1008.   /*    Routines to manage various kinds of resources:
  1009.    *
  1010. ***************
  1011. *** 169,176 ****
  1012.       pointer value;
  1013.       int (* func)();
  1014.   {
  1015. !     int client, j;
  1016. !     ResourcePtr res, next, *head;
  1017.           
  1018.       client = CLIENT_ID(id);
  1019.       if (!clientTable[client].buckets)
  1020. --- 169,177 ----
  1021.       pointer value;
  1022.       int (* func)();
  1023.   {
  1024. !     int client;
  1025. !     register int j;
  1026. !     register ResourcePtr res, next, *head;
  1027.           
  1028.       client = CLIENT_ID(id);
  1029.       if (!clientTable[client].buckets)
  1030. ***************
  1031. *** 195,206 ****
  1032.       clientTable[client].hashsize++;
  1033.       for (j = 0; j < clientTable[client].buckets; j++)
  1034.       {
  1035.           for (res = clientTable[client].resources[j]; res; res = next)
  1036.           {
  1037.           next = res->next;
  1038.           head = &resources[Hash(client, res->id)];
  1039. !         res->next = *head;
  1040.           *head = res;
  1041.           }
  1042.       }
  1043.       clientTable[client].buckets *= 2;
  1044. --- 196,213 ----
  1045.       clientTable[client].hashsize++;
  1046.       for (j = 0; j < clientTable[client].buckets; j++)
  1047.       {
  1048. +         /*
  1049. +          * Must preserve insertion order so that FreeResource doesn't free
  1050. +          * "subclasses" before main resources are freed.  Sigh.
  1051. +          */
  1052.           for (res = clientTable[client].resources[j]; res; res = next)
  1053.           {
  1054.           next = res->next;
  1055.           head = &resources[Hash(client, res->id)];
  1056. !         while (*head)
  1057. !             head = &(*head)->next;
  1058.           *head = res;
  1059. +         res->next = NullResource;
  1060.           }
  1061.       }
  1062.       clientTable[client].buckets *= 2;
  1063.  
  1064.  
  1065. *** /tmp/,RCSt1a03822    Thu Jan 12 17:43:12 1989
  1066. --- server/ddx/cfb/cfbscrinit.c    Thu Jan 12 17:41:35 1989
  1067. ***************
  1068. *** 64,70 ****
  1069.       8,        1,        NULL,
  1070.   };
  1071.   
  1072. - static ColormapPtr cfbColorMaps[NUMVISUALS];    /* assume one per visual */
  1073.   #define NUMDEPTHS    ((sizeof depths)/(sizeof depths[0]))
  1074.   
  1075.   /* dts * (inch/dot) * (25.4 mm / inch) = mm */
  1076. --- 64,69 ----
  1077. ***************
  1078. *** 80,85 ****
  1079. --- 79,85 ----
  1080.       register PixmapPtr pPixmap;
  1081.       int    i;
  1082.       void cfbInitialize332Colormap();
  1083. +     ColormapPtr cmap;
  1084.   
  1085.       pScreen->myNum = index;
  1086.       pScreen->width = xsize;
  1087. ***************
  1088. *** 171,195 ****
  1089.       visuals[i].screen = index;
  1090.       AddResource(visuals[i].vid, RT_VISUALID, (pointer)&visuals[i],
  1091.               NoopDDA, RC_CORE);
  1092. -     switch (visuals[i].class) {
  1093. -     case StaticGray:
  1094. -     case StaticColor:
  1095. -         CreateColormap(FakeClientID(0), pScreen, &visuals[i], 
  1096. -         &cfbColorMaps[i], AllocAll, 0);
  1097. -         break;
  1098. -     case PseudoColor:
  1099. -     case GrayScale:
  1100. -         CreateColormap(FakeClientID(0), pScreen, &visuals[i], 
  1101. -         &cfbColorMaps[i], AllocNone, 0);
  1102. -         break;
  1103. -     case TrueColor:
  1104. -     case DirectColor:
  1105. -         FatalError("Bad visual in cfbScreenInit\n");
  1106. -     }
  1107. -     if (!cfbColorMaps[i])
  1108. -         FatalError("Can't create colormap in cfbScreenInit\n");
  1109.       }
  1110. -     pScreen->defColormap = cfbColorMaps[ROOTVISUAL]->mid;
  1111.       pScreen->rootVisual = visuals[ROOTVISUAL].vid;
  1112.   
  1113.       /*  Set up the remaining fields in the depths[] array */
  1114. --- 171,177 ----
  1115. ***************
  1116. *** 201,206 ****
  1117. --- 183,207 ----
  1118.           pVids[0] = visuals[ROOTVISUAL].vid;
  1119.       }
  1120.       }
  1121. +     pScreen->defColormap = FakeClientID(0);
  1122. +     switch (visuals[ROOTVISUAL].class) {
  1123. +     case StaticGray:
  1124. +     case StaticColor:
  1125. +     CreateColormap(pScreen->defColormap, pScreen, &visuals[ROOTVISUAL],
  1126. +                &cmap, AllocAll, 0);
  1127. +     break;
  1128. +     case PseudoColor:
  1129. +     case GrayScale:
  1130. +     CreateColormap(pScreen->defColormap, pScreen, &visuals[ROOTVISUAL], 
  1131. +                &cmap, AllocNone, 0);
  1132. +     break;
  1133. +     case TrueColor:
  1134. +     case DirectColor:
  1135. +     FatalError("Bad visual in cfbScreenInit\n");
  1136. +     }
  1137. +     if (!cmap)
  1138. +     FatalError("Can't create colormap in cfbScreenInit\n");
  1139.       return( TRUE );
  1140.   }
  1141.   
  1142.  
  1143. *** old/lib/Xt/TMstate.c
  1144. --- lib/Xt/TMstate.c
  1145. ***************
  1146. *** 1,5 ****
  1147.   #ifndef lint
  1148. ! static char Xrcsid[] = "$XConsortium: TMstate.c,v 1.65 89/01/20 08:05:17 swick Exp $";
  1149.   /* $oHeader: TMstate.c,v 1.5 88/09/01 17:17:29 asente Exp $ */
  1150.   #endif lint
  1151.   /*LINTLIBRARY*/
  1152. --- 1,5 ----
  1153.   #ifndef lint
  1154. ! static char Xrcsid[] = "$XConsortium: TMstate.c,v 1.67 89/01/30 15:01:40 swick Exp $";
  1155.   /* $oHeader: TMstate.c,v 1.5 88/09/01 17:17:29 asente Exp $ */
  1156.   #endif lint
  1157.   /*LINTLIBRARY*/
  1158. ***************
  1159. *** 86,128 ****
  1160.       Boolean notfirst = False;
  1161.       CHECK_STR_OVERFLOW;
  1162.   
  1163. ! #if defined(__STDC__) && !defined(UNIXCPP)
  1164. ! #define MASKNAME(modname) modname##Mask
  1165. ! #else
  1166. ! #define MASKNAME(modname) modname/**/Mask
  1167. ! #endif
  1168. ! #define PRINTMOD(modname) \
  1169. !     if (mask & MASKNAME(modname)) {     \
  1170. !     if (! (mod & MASKNAME(modname))) \
  1171.           *str++ = '~';         \
  1172.       else if (notfirst)         \
  1173.           *str++ = ' ';         \
  1174.       *str = '\0';             \
  1175. !     strcat(str, "modname");         \
  1176.       str += strlen(str);         \
  1177. -     notfirst = True;         \
  1178.       }
  1179.   
  1180. ! #define CtrlMask ControlMask
  1181.   
  1182. -     PRINTMOD(Shift);
  1183. -     PRINTMOD(Ctrl);
  1184. -     PRINTMOD(Lock);
  1185. -     PRINTMOD(Mod1);
  1186. -     PRINTMOD(Mod2);
  1187. -     PRINTMOD(Mod3);
  1188. -     PRINTMOD(Mod4);
  1189. -     PRINTMOD(Mod5);
  1190. -     PRINTMOD(Button1);
  1191. -     PRINTMOD(Button2);
  1192. -     PRINTMOD(Button3);
  1193. -     PRINTMOD(Button4);
  1194. -     PRINTMOD(Button5);
  1195. - #undef MASKNAME
  1196.   #undef PRINTMOD
  1197. - #undef CtrlMask
  1198.   
  1199.       return str;
  1200.   }
  1201. --- 86,120 ----
  1202.       Boolean notfirst = False;
  1203.       CHECK_STR_OVERFLOW;
  1204.   
  1205. ! #define PRINTMOD(modmask,modstring) \
  1206. !     if (mask & modmask) {         \
  1207. !     if (! (mod & modmask)) {     \
  1208.           *str++ = '~';         \
  1209. +         notfirst = True;         \
  1210. +     }                 \
  1211.       else if (notfirst)         \
  1212.           *str++ = ' ';         \
  1213. +     else notfirst = True;         \
  1214.       *str = '\0';             \
  1215. !     strcat(str, modstring);         \
  1216.       str += strlen(str);         \
  1217.       }
  1218.   
  1219. !     PRINTMOD(ShiftMask, "Shift");
  1220. !     PRINTMOD(ControlMask, "Ctrl");    /* name is not CtrlMask... */
  1221. !     PRINTMOD(LockMask, "Lock");
  1222. !     PRINTMOD(Mod1Mask, "Mod1");
  1223. !     PRINTMOD(Mod2Mask, "Mod2");
  1224. !     PRINTMOD(Mod3Mask, "Mod3");
  1225. !     PRINTMOD(Mod4Mask, "Mod4");
  1226. !     PRINTMOD(Mod5Mask, "Mod5");
  1227. !     PRINTMOD(Button1Mask, "Button1");
  1228. !     PRINTMOD(Button2Mask, "Button2");
  1229. !     PRINTMOD(Button3Mask, "Button3");
  1230. !     PRINTMOD(Button4Mask, "Button4");
  1231. !     PRINTMOD(Button5Mask, "Button5");
  1232.   
  1233.   #undef PRINTMOD
  1234.   
  1235.       return str;
  1236.   }
  1237. -- 
  1238. Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
  1239. Moderator of comp.sources.x
  1240.